package leetcode.util;

import leetcode.剑指offer.pojo.ListNode;
import leetcode.剑指offer.pojo.TreeNode;
import leetcode.每日一题.二叉搜索树中的插入操作;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author ：zsy
 * @date ：Created 2021/8/7 17:09
 * @description：工具类
 */
@Slf4j
public class CommonUtils {

    private CommonUtils() {
    }


    // =================== Array ============================ //

    public static final int DEFAULT_MAX_VALUE = 100;
    public static final int DEFAULT_MAX_LEN = 10;

    /**
     *  生成排序数组
     * @param args 0:最大长度 1:最大值 2: 1升序(默认);-1降序
     * @return
     */
    public static int[] genSortedIntArray(int ...args) {
        int maxLen = DEFAULT_MAX_LEN;
        int maxValue = DEFAULT_MAX_VALUE;
        int flagSort = 1;
        if (args.length > 0) {
            maxLen = args[0];
        }
        if (args.length > 1) {
            maxValue = args[1];
        }
        if (args.length > 2) {
            flagSort = args[2];
        }
        // gen sorted array asc
        int[] arr = new int[maxLen];
        for (int i = 0; i < maxLen; i++) {
            arr[i] = (int)(Math.random() * maxValue + 1);
        }
        if (flagSort == 1) {
            arr = Arrays.stream(arr).sorted().toArray();
        } else {
            arr = Arrays.stream(arr).boxed().sorted(((o1, o2) -> o2 - o1)).mapToInt(int1 -> int1).toArray();
        }
        log.info(Arrays.toString(arr));
        return arr;
    }

    // =================== ListNode ============================ //

    public static void printListNode(ListNode head) {
        if (head == null) return;
        ListNode tmp = head;
        StringBuilder builder = new StringBuilder();
        while (tmp != null) {
            builder.append(tmp.val).append("->");
            tmp = tmp.next;
        }
        System.out.println(builder.substring(0, builder.length() - 2));
    }

    /**
     * list listNode
     * @param head
     */
    public static void list_listNode(ListNode head) {
        ListNode tmp = head;
        ArrayList<Integer> ans = new ArrayList<>();
        while (tmp != null) {
            ans.add(tmp.val);
            tmp = tmp.next;
        }
        System.out.println(ans);
    }

    /**
     * transfer arr to listNode
     * @param arr
     * @return
     */
    public static ListNode transferArrToListNode(int[] arr) {
        if (arr.length == 0) return null;
        ListNode head = new ListNode(-1);
        ListNode tmp = head;
        for (int a : arr) {
            tmp.next = new ListNode(a);
            tmp = tmp.next;
        }
        return head.next;
    }

    // =================== Array ============================ //

    /**
     * charge array idx i & j
     * @param arr
     * @param i
     * @param j
     */
    public static void charge(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * transfer arr like from [1, 2, 3] to {1, 2, 3}
     * @param str
     */
    public static void arrTransfer(String str) {
        StringBuilder builder = new StringBuilder();
        for (char ch : str.toCharArray()) {
            if (ch == '[') {
                builder.append("{");
                continue;
            } else if (ch == ']') {
                builder.append("}");
                continue;
            }
            builder.append(ch);
        }
        System.out.println(builder);
    }

    public static void print2Arr(int[][] arr) {
        for (int[] a : arr) {
            System.out.println(Arrays.toString(a));
        }
    }

    // =================== TreeNode ============================ //

    /**
     * Print TreeNode by layer
     * @param root
     */
    public static void printTreeNodeByLayer(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        int height = height(root);
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            height--;
            String preChar = String.join("", Collections.nCopies(2 * height + 1, " "));
            String preNum = String.join("", Collections.nCopies(3 * height + 2, " "));
            StringBuilder charBuilder = new StringBuilder();
            StringBuilder numBuilder = new StringBuilder();
            for (int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                numBuilder.append(preNum).append(cur.val);

                if (cur.left != null) {
                    charBuilder.append(preChar).append("/");
                    queue.offer(cur.left);
                } else {
                    charBuilder.append(preChar).append(" ");
                }
                if (cur.right != null) {
                    charBuilder.append(preChar).append("\\");
                    queue.offer(cur.right);
                } else {
                    charBuilder.append(preChar).append(" ");
                }
            }
            System.out.println(numBuilder);
            System.out.println(charBuilder);
        }
    }

    /**
     * calc TreeNode height
     * @param node
     * @return
     */
    public static int height(TreeNode node) {
        return node == null ? 0 : Math.max(height(node.left), height(node.right)) + 1;
    }

    // =================== BST TreeNode ============================ //

}
